﻿using System;

namespace Guesshoo.TrainExpress
{
	/// <summary>
	/// Design by contract utility; used to check object contract adherence by client objects
	/// </summary>
	public static class DBC
	{
		//Not worried about differentiating between pre/post conditions and invariants here

		public static void AssertNotNull(object pObject, string pMessage,
		                                 params string[] pArguments) {
			AssertNotNull(pObject, String.Format(pMessage, pArguments));
		}

		/// <summary>
		/// Assert that the object is not null; any type
		/// </summary>
		/// <param name="pObject"></param>
		/// <param name="pMessage"></param>
		/// <exception cref="AssertionFailureException">If the assertion condition would be false</exception> 
		public static void AssertNotNull(object pObject, string pMessage) {
			Assert(pObject != null, pMessage);
		}

		/// <summary>
		/// Assert that the object is not null; use with string types only
		/// </summary>
		/// <param name="pString"></param>
		/// <param name="pMessage"></param>
		/// <exception cref="AssertionFailureException">If the assertion condition would be false</exception> 
		public static void AssertNotNullOrEmpty(string pString, string pMessage) {
			Assert(pString != null && pString.Trim() != String.Empty, pMessage);
		}

		/// <summary>
		/// Assert that the condition is true
		/// </summary>
		/// <param name="pCondition"></param>
		/// <param name="pMessage"></param>
		/// <exception cref="AssertionFailureException">If the assertion condition would be false</exception> 
		public static void Assert(bool pCondition, string pMessage) {
			if (!pCondition) {
				throw new AssertionFailureException(pMessage);
			}
			//Debug.Assert(pCondition, pMessage);
		}

		public static void Assert(bool pCondition, string pMessage,
		                          params string[] pArguments) {
			Assert(pCondition, String.Format(pMessage, pArguments));
		}
	}

	/// <summary>
	/// Thrown by the DBC class when an assertion fails
	/// </summary>
	[Serializable]
	public class AssertionFailureException : ApplicationException
	{
		public AssertionFailureException() {}

		public AssertionFailureException(string pMessage)
			: base(pMessage) {}

		public AssertionFailureException(string pMessage, Exception pException)
			: base(pMessage, pException) {}
	}
}